package com.xhwl.centiotdata.handler.pedestrian.impl;

import com.alibaba.fastjson.JSONObject;
import com.xhwl.centiotdata.handler.pedestrian.PedestrianIntegrationFactory;
import com.xhwl.centiotdata.handler.pedestrian.PedestrianIntegrationHandler;
import com.xhwl.centiotdata.pojo.constant.HaiKangYunMouConstant;
import com.xhwl.centiotdata.pojo.dto.haikangyunmou.HaiKangYunMouJson;
import com.xhwl.centiotdata.pojo.dto.haikangyunmou.HaiKangYunMouProject;
import com.xhwl.centiotdata.pojo.dto.pedestrian.PedestrianIntegrationConfigDTO;
import com.xhwl.centiotdata.pojo.dto.visitor.VisitorIntegrationConfigDTO;
import com.xhwl.centiotdata.service.cent.IAuthAccountCentService;
import com.xhwl.centiotdata.service.cent.IDeviceCentService;
import com.xhwl.centiotdata.service.impl.AccountServiceImpl;
import com.xhwl.centiotdata.suppliersystem.haikangyunmou.HaiKangYunMouUtils;
import com.xhwl.centiotdata.suppliersystem.haikangyunmou.PedestrianHaiKangYunMouHandler;
import com.xhwl.centiotdata.suppliersystem.haikangyunmou.UserHaiKangYunMouHandler;
import com.xhwl.common.dto.auth.PedestrianAuthDTO;
import com.xhwl.common.dto.cent.device.DeviceDTO;
import com.xhwl.common.dto.cent.pedes.DeviceHaiKangDTO;
import com.xhwl.common.dto.cent.pedes.UserDTO;
import com.xhwl.common.enums.CategoryEnum;
import com.xhwl.common.enums.ProductEnum;
import com.xhwl.common.enums.device.DeviceTypeEnum;
import com.xhwl.common.pojo.ResultJson;
import com.xhwl.common.pojo.cent.auth.AuthAccountMapping;
import com.xhwl.common.query.cent.device.DeviceQuery;
import com.xhwl.common.utils.StringUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @Author： guan
 * @Description：海康云眸
 * @Date 2022/05/12/ 13:48
 */
@Slf4j
@Service
public class PedestrianIntegrationHaiKangYunMouHandler extends PedestrianIntegrationHandler {

    @Autowired
    private PedestrianHaiKangYunMouHandler pedestrianHaiKangYunMouHandler;
    @Autowired
    private AccountServiceImpl accountService;
    @Autowired
    private UserHaiKangYunMouHandler userHaiKangYunMouHandler;
    @Autowired
    private IAuthAccountCentService authAccountCentService;
    @Autowired
    private HaiKangYunMouUtils haiKangYunMouUtils;
    @Autowired
    private IDeviceCentService deviceCentService;

    @Override
    public void afterPropertiesSet() throws Exception {
        PedestrianIntegrationFactory.register(ProductEnum.HAIKANG_YUNMOU.getId(), this);
    }

    @Override
    public void syncThirdAuthorizedDoorInfo(PedestrianAuthDTO pedestrianAuthDTO, PedestrianIntegrationConfigDTO configDTO) {
        // 查询项目下的门禁设备
        List<DeviceDTO> deviceDTOList = listDeviceDTO(configDTO.getProjectId());
        if (CollectionUtils.isEmpty(deviceDTOList)) {
            log.info("项目{}未同步子系统设备,终止", configDTO.getProjectId());
            return;
        }

        // 查询项目人员的第三方用户id
        List<AuthAccountMapping> authAccountMappingList = authAccountCentService.list(configDTO.getProjectId(), null, null);
        if (StringUtils.isNotEmpty(pedestrianAuthDTO.getUserOpenId())) {
            authAccountMappingList = authAccountMappingList.stream().filter(obj -> Objects.equals(obj.getOpenId(), pedestrianAuthDTO.getUserOpenId())).collect(Collectors.toList());
        }
        if(CollectionUtils.isEmpty(authAccountMappingList)) {
            log.info("项目{}未同步人员到子系统", configDTO.getProjectId());
            return;
        }

        // 根据项目id获取社区id
        List<String> communityIds = haiKangYunMouUtils.getCommunityId(configDTO.getProjectId(),pedestrianAuthDTO.getSourceId());
        log.info("获取的社区idList{}", communityIds);

        // 封装待同步权限的业务数据
        List<PedestrianAuthDTO> pedestrianAuthDTOS = new ArrayList<>(16);
        authAccountMappingList.forEach(authAccountMapping -> {
            String personId = authAccountMapping.getOpenId();
            VisitorIntegrationConfigDTO visitorIntegrationConfigDTO = new VisitorIntegrationConfigDTO();
            BeanUtils.copyProperties(configDTO, visitorIntegrationConfigDTO);
            List<DeviceHaiKangDTO> authList = new ArrayList<>(16);

            communityIds.forEach(communityId -> {
                HaiKangYunMouJson resp = haiKangYunMouUtils.getAuthDevices(personId, communityId, visitorIntegrationConfigDTO);
                log.info("{}获取授权设备响应结果{}", personId, resp);
                if (!resp.getCode().equals(HaiKangYunMouConstant.SUCCESS_CODE)) {
                    log.error("获取{}的子系统权限失败,openId:{},社区id：{}", authAccountMapping.getAccountId(), personId, communityId);
                    return;
                }
                authList.addAll(JSONObject.parseArray(JSONObject.toJSONString(resp.getData()), DeviceHaiKangDTO.class));
            });
            if (CollectionUtils.isEmpty(authList)) {
                log.error("获取{}的子系统权限为空,openId:{},社区id：{}", authAccountMapping.getAccountId(), personId, communityIds);
                return;
            }

            List<String> authThirdDeviceIdList = authList.stream().map(DeviceHaiKangDTO::getDeviceId).collect(Collectors.toList());
            PedestrianAuthDTO retPedestrianAuthDTO = new PedestrianAuthDTO();
            retPedestrianAuthDTO.setProjectId(configDTO.getProjectId());
            retPedestrianAuthDTO.setProductId(configDTO.getProductId());
            retPedestrianAuthDTO.setUserOpenId(personId);
            retPedestrianAuthDTO.setThirdDeviceIdList(authThirdDeviceIdList);
            pedestrianAuthDTOS.add(retPedestrianAuthDTO);
        });

        // 同步子系统权限至兴海
        if (!CollectionUtils.isEmpty(pedestrianAuthDTOS)) {
            authAccountCentService.syncThirdAuthorizedInfo(pedestrianAuthDTOS);
        }
    }

    /**
     * 拉取海康云眸门禁出入记录
     *
     * @param config
     * @param intervalDays
     * @param date
     */
    @Override
    public void pullRecord(PedestrianIntegrationConfigDTO config, Integer intervalDays, Date date) {
        pedestrianHaiKangYunMouHandler.pullRecord(config);
    }

    @Override
    public ResultJson createAuth(PedestrianIntegrationConfigDTO configDTO, PedestrianAuthDTO pedestrianAuthDTO) {
        log.info("海康云眸人员授权开始,configDTO:{}, pedestrianAuthDTO:{}", JSONObject.toJSONString(configDTO), JSONObject.toJSONString(pedestrianAuthDTO));
        String userOpenId = null;
        if (StringUtils.isEmpty(pedestrianAuthDTO.getUserOpenId())) {
            UserDTO userDTO = accountService.queryUser(pedestrianAuthDTO.getIndustryId(),
                    pedestrianAuthDTO.getProjectId(), pedestrianAuthDTO.getSourceId());
            // 如果没有查到人脸图片并且传过来的参数有人脸照片用传过来的参数的
            if (!StringUtils.isEmpty((pedestrianAuthDTO.getFaceUrl()))){
                userDTO.setFaceUrl(pedestrianAuthDTO.getFaceUrl());
            }
            log.info("海康云眸人行查询中台人员：{}", JSONObject.toJSONString(userDTO));
            try {
                // 先查authAccountMapping中是否存在openId
                userOpenId = authAccountCentService.queryOpenId(configDTO.getProjectId(),pedestrianAuthDTO.getSourceId(),null,configDTO.getProductId());
                if (StringUtils.isEmpty(userOpenId)){
                    // 从批量导入处获取人员open_id,此处null为open_id的传值，0为批量导入住户信息时product_id的传值
                    userOpenId = authAccountCentService.queryOpenId(configDTO.getProjectId(),pedestrianAuthDTO.getSourceId(),null,0);
                    if (StringUtils.isEmpty(userOpenId)){
                        userOpenId = userHaiKangYunMouHandler.addPerson(userDTO,configDTO,pedestrianAuthDTO.getSourceId());
                        log.info("海康云眸新增住户人员信息：{}", userOpenId);
                    }
                    if(StringUtils.isNotEmpty(userOpenId)) {
                        authAccountCentService.save(configDTO.getProjectId(), pedestrianAuthDTO.getSourceId(), userOpenId, null, configDTO.getProductId());
                    }
                }
                // 设置所属社区
                List<HaiKangYunMouProject> yunMouBuildings = haiKangYunMouUtils.getDefaultYunMouConfigByProjectId(configDTO.getProjectId(), pedestrianAuthDTO.getSourceId());
                if (!CollectionUtils.isEmpty(yunMouBuildings)){
                    String finalUserOpenId = userOpenId;
                    yunMouBuildings.forEach(yunMouBuilding -> {
                        if (yunMouBuilding == null || StringUtils.isEmpty(yunMouBuilding.getCommunityId()) || StringUtils.isEmpty(yunMouBuilding.getRoomId())) {
                            userHaiKangYunMouHandler.addCommunityRelation(finalUserOpenId, configDTO,pedestrianAuthDTO.getSourceId());
                        }
                    });
                }

            } catch (Exception e) {
                log.error("海康云眸新增住户人员信息失败：{}", e.toString());
                return ResultJson.fail("海康云眸新增住户人员信息失败：" + e.getMessage());
            }
        } else {
            userOpenId = pedestrianAuthDTO.getUserOpenId();
        }

        // 给第三方进行授权
        List<String> personIds = Arrays.asList(userOpenId);
        List<String> deviceIds = pedestrianAuthDTO.getAddedThirdDeviceIdList();
        log.info("hik-cloud:createAuth,personIds:{}, deviceIds:{}", personIds, deviceIds);
        if (!CollectionUtils.isEmpty(deviceIds)) {
            try {
                pedestrianHaiKangYunMouHandler.addAuth(configDTO, personIds, deviceIds,pedestrianAuthDTO.getSourceId());
            } catch (Exception e) {
                log.error("hik-cloud:addAuth fail, personIds:{}, deviceIds:{}", personIds, deviceIds);
                return ResultJson.fail("海康云眸住户人员权限批量下发失败：" + e.getMessage());
            }
        }
        try {
            onSavingAuthCards(authAccountCentService, configDTO, pedestrianAuthDTO);
        } catch (Exception e) {
            // 保存转换卡号数据失败
            log.error("卡号转换失败{}",e);
        }
        return ResultJson.success();
    }

    @Override
    public ResultJson updateAuth(PedestrianIntegrationConfigDTO configDTO, PedestrianAuthDTO pedestrianAuthDTO) {
        log.info("人行更新授权开始：");
        log.info("updateAuth configDTO:{}, pedestrianAuthDTO:{}", JSONObject.toJSONString(configDTO), JSONObject.toJSONString(pedestrianAuthDTO));
        // 更新人员信息
        UserDTO userDTO = accountService.queryUser(pedestrianAuthDTO.getIndustryId(),
                pedestrianAuthDTO.getProjectId(), pedestrianAuthDTO.getSourceId());
        // 如果没有查到人脸图片并且传过来的参数有人脸照片用传过来的参数的
        if (StringUtils.isEmpty(userDTO.getFaceUrl())&&!StringUtils.isEmpty((pedestrianAuthDTO.getFaceUrl()))){
            userDTO.setFaceUrl(pedestrianAuthDTO.getFaceUrl());
        }
        log.info("海康云眸人行查询中台人员：{}",JSONObject.toJSONString(userDTO));
        String userOpenId = authAccountCentService.queryOpenId(configDTO.getProjectId(),pedestrianAuthDTO.getSourceId(),null,configDTO.getProductId());
        log.error("userOpenId{}",userOpenId);
        if (StringUtils.isNotEmpty(userOpenId)){
            userHaiKangYunMouHandler.updatePerson(userDTO,configDTO,userOpenId);
        }
        // 先删除
        List<String> delDeviceIds = pedestrianAuthDTO.getDeletedThirdDeviceIdList();
        List<String> personIds = Arrays.asList(pedestrianAuthDTO.getUserOpenId());
        if (!CollectionUtils.isEmpty(delDeviceIds)) {
            try {
                log.info("删除授权设备：{}", delDeviceIds);
                pedestrianHaiKangYunMouHandler.deleteAuth(configDTO, personIds, delDeviceIds,pedestrianAuthDTO.getSourceId());
            } catch (Exception e) {
                log.error("hik-cloud:deleteAuth fail：{}", e.getMessage());
                return ResultJson.fail("海康云眸人员权限删除失败:" + e.getMessage());
            }
        }
        List<String> deviceIds = pedestrianAuthDTO.getThirdDeviceIdList();
        log.info("hik-cloud:updateAuth,personIds:{}, deviceIds:{}", personIds, deviceIds);
        if (!CollectionUtils.isEmpty(deviceIds)) {
            // 再添加
            try {
                pedestrianHaiKangYunMouHandler.addAuth(configDTO, personIds, deviceIds,pedestrianAuthDTO.getSourceId());
            } catch (Exception e) {
                log.error("hik-cloud:addAuth fail：{}", e.getMessage());
                return ResultJson.fail("海康云眸住户人员权限批量下发失败:" + e.getMessage());
            }
        }
        return ResultJson.success();
    }

    @Override
    public ResultJson deleteAuth(PedestrianIntegrationConfigDTO configDTO, PedestrianAuthDTO pedestrianAuthDTO) {
        log.info("人行删除授权开始：");
        log.info("deleteAuth configDTO:{}, pedestrianAuthDTO:{}", JSONObject.toJSONString(configDTO), JSONObject.toJSONString(pedestrianAuthDTO));
        List<String> deviceIds = pedestrianAuthDTO.getDeletedThirdDeviceIdList();
        List<String> personIds = Arrays.asList(pedestrianAuthDTO.getUserOpenId());
        log.info("hik-cloud:deleteAuth,personIds:{}, deviceIds:{}", personIds, deviceIds);
        if (!CollectionUtils.isEmpty(deviceIds)) {
            try {
                pedestrianHaiKangYunMouHandler.deleteAuth(configDTO, personIds, deviceIds,pedestrianAuthDTO.getSourceId());
            } catch (Exception e) {
                log.error("hik-cloud:deleteAuth fail：{}", e.getMessage());
                return ResultJson.fail("海康云眸人员权限删除失败" + e.getMessage());
            }
        }
        return ResultJson.success();
    }

    /**
     * 获取项目的设备信息
     *
     * @param projectId 项目id
     * @return result
     */
    private List<DeviceDTO> listDeviceDTO(Integer projectId) {
        DeviceQuery deviceQuery = new DeviceQuery();
        deviceQuery.setProjectId(projectId);
        deviceQuery.setCategoryIdList(Collections.singletonList(CategoryEnum.DOOR.getId()));
        deviceQuery.setDeviceTypeId(DeviceTypeEnum.DOOR.getCode());
        return deviceCentService.listDevice(null, deviceQuery);
    }

}
